﻿package dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.Query;

import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Example;

public abstract class AbstractDAO<T, E> implements IDAO<T, E>{

	private Class<T> entityClass;
	protected static EntityManager entityManager;

	
	public AbstractDAO(Class<T> entityClass) {
		entityManager = DatabaseConnector.getEntityManager();
		this.entityClass = entityClass;
	}

	@Override
	public T merge(T obj){
		T result = null;
		try {
			entityManager.getTransaction().begin();
		
			result = entityManager.merge(obj);
			
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
		}
		return result;
	}

	@Override
	public void delete(T obj){
		try {
			entityManager.getTransaction().begin();
	        entityManager.remove(obj);
	        entityManager.getTransaction().commit();
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
		}
	}
	
	public void deleteByID(E id){
		try {
	        delete(entityManager.getReference(entityClass, id));
		} catch (EntityNotFoundException  e) {
			System.out.println("MangageBehavior - Entity Not Found");
		}
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public List<T> selectAll(){
		Query query = entityManager.createQuery("SELECT o FROM "+entityClass.getSimpleName()+" o");
		return query.getResultList();
	}

	@Override
	public T persist(T obj){
		try {
			entityManager.getTransaction().begin();
			entityManager.persist(obj);
			entityManager.getTransaction().commit();

			return obj;
		} catch (Exception e) {
			entityManager.getTransaction().rollback();
		}
		return null;
	}

	@Override
	public T findByID(E id) {
		return entityManager.find(entityClass, id);
	
	}
	
	@Override
	public void refresh(T obj) {
		entityManager.refresh(obj);
		
	}
	
	/////////////////////////////////////
	////BEGIN: Cac cau lenh su dung bien Session cua hibernate 
	/**
	 * Lenh tim theo dieu kien - Native Hibernate
	 */
	@SuppressWarnings("unchecked")
	public List<T> findByCriteria(Criterion... criterion) {
        Criteria crit = DatabaseConnector.getHibernateSession().createCriteria(entityClass);
        for (Criterion c : criterion) {
            crit.add(c);
        }
        return crit.list();
   }

	@SuppressWarnings("unchecked")
	@Override
	public List<T> findByExample(T exampleInstance, String[] excludeProperty) {
        Criteria crit = DatabaseConnector.getHibernateSession().createCriteria(entityClass);
        Example example =  Example.create(exampleInstance);
        for (String exclude : excludeProperty) {
            example.excludeProperty(exclude);
        }
        crit.add(example);
        return crit.list();
    }
	
	////END: Cac cau lenh su dung bien Session cua hibernate
	
	public T findReference(E id){
		return entityManager.getReference(entityClass, id);
	}
}
